package com.du.limiting.sentinel.runner;

import com.alibaba.csp.sentinel.slots.block.RuleConstant;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowItem;
import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowRuleManager;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.du.limiting.sentinel.entity.ParamFlowItemEntity;
import com.du.limiting.sentinel.entity.ParamFlowRuleEntity;
import com.du.limiting.sentinel.mapper.ParamFlowItemDao;
import com.du.limiting.sentinel.mapper.ParamFlowRuleDao;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * @author dujunguang
 * @date 2022/2/23 11:07
 * @description: TODO
 **/
//@Component
public class SentinelConfigDataRunner implements CommandLineRunner {

    @Resource
    private ParamFlowRuleDao paramFlowRuleDao;

    @Resource
    private ParamFlowItemDao paramFlowItemDao;


    @Override
    public void run(String... args) throws Exception {

        // 流控规则
        List<FlowRule> rules = new ArrayList<>();
        FlowRule rule1 = new FlowRule();
        rule1.setResource("hotPoint");
        rule1.setCount(10);
        rule1.setGrade(RuleConstant.FLOW_GRADE_QPS);
        rule1.setLimitApp("lisi");
        rules.add(rule1);
        FlowRuleManager.loadRules(rules);


        // 热点规则
//        List<ParamFlowRuleEntity> paramFlowRuleEntities = initDataSourceFlowRule();
//        List<ParamFlowRule> ruleList = new ArrayList<>();
//        for (ParamFlowRuleEntity paramFlowRule : paramFlowRuleEntities) {
//            List<ParamFlowItemEntity> flowItemList = getFlowItemList(paramFlowRule.getId());
//
//            ParamFlowRule rule = new ParamFlowRule(paramFlowRule.getResource())
//                    .setParamIdx(paramFlowRule.getParamIdx())
//                    .setCount(paramFlowRule.getCount())
//                    .setDurationInSec(paramFlowRule.getDurationinSec());
//            List<ParamFlowItem> itemList = new ArrayList<>();
//            for (ParamFlowItemEntity flowItem : flowItemList) {
//                // 针对 String 类型的参数 name，单独设置限流 QPS 阈值为 8，而不是全局的阈值 5.
//                ParamFlowItem item = new ParamFlowItem()
//                        .setObject(flowItem.getObject())
//                        .setClassType(flowItem.getClassType())
//                        .setCount(flowItem.getCount());
//                itemList.add(item);
//            }
//
//            rule.setParamFlowItemList(itemList);
//            ruleList.add(rule);
//        }
//        ParamFlowRuleManager.loadRules(ruleList);
    }


    public List<ParamFlowRuleEntity> initDataSourceFlowRule() {
        QueryWrapper<ParamFlowRuleEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("deleted", 0);
        return paramFlowRuleDao.selectList(queryWrapper);
    }

    public List<ParamFlowItemEntity> getFlowItemList(Long ruleId) {
        QueryWrapper<ParamFlowItemEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("rule_id", ruleId);
        queryWrapper.eq("deleted", 0);
        return paramFlowItemDao.selectList(queryWrapper);
    }


    public void init() {
        // 资源名
        ParamFlowRule rule = new ParamFlowRule("hotUser")
                .setParamIdx(0)
                // qps
                .setGrade(RuleConstant.FLOW_GRADE_QPS)
                // 统计窗口时长
                .setDurationInSec(3)
                // 流控效果，默认为0，快速失败模式
                .setControlBehavior(RuleConstant.CONTROL_BEHAVIOR_RATE_LIMITER)
                .setCount(5);

        // 热点项设置
        ParamFlowItem item = new ParamFlowItem()
                .setObject("lisi")
                .setClassType(String.class.getName())
                .setCount(10);
        rule.setParamFlowItemList(Collections.singletonList(item));
        ParamFlowRuleManager.loadRules(Collections.singletonList(rule));
    }

}
